(function() {
	var GOOGLE_BASE_URL = 'http://maps.googleapis.com/maps/geo?output=json&q=';
	
	var gps = {};
	gps.getCurrentPosition = function(callback) {
		var currentLocationInfo = null;
		if ($.is_debug()) {
			gps.getGeocodeNative(L('debug_location_address'), callback);
		} else {
			Ti.Geolocation.purpose = '';
			Ti.Geolocation.getCurrentPosition(function(e) {
				if (e && e.success && e.coords) {
					var latitude = e.coords.latitude;
					var longitude = e.coords.longitude;
					var heading = e.coords.heading;
					var accuracy = e.coords.accuracy;
					var speed = e.coords.speed;
					var timestamp = e.coords.timestamp;
					currentLocationInfo = $.model('location')(latitude, longitude, heading, accuracy, speed, timestamp);
					callback && callback(currentLocationInfo);
				}
			});
		}
	};
	gps.getGeocodeNative = function(address, callback) {
		var xhr = Ti.Network.createHTTPClient();
		xhr.open('GET', GOOGLE_BASE_URL + address);
		xhr.onload = function() {
			var json = JSON.parse(this.responseText);
			if (!json.Placemark || !json.Placemark[0].Point || !json.Placemark[0].Point.coordinates) {
				if (callback)
					callback(currentLocationInfo);
			} else {
				var currentLocationInfo = $.model('location')(json.Placemark[0].Point.coordinates[1], json.Placemark[0].Point.coordinates[0], null, null, null, null);
				if (callback)
					callback(currentLocationInfo);
			}
		};
		xhr.onerror = function(e) {
		};
		xhr.send();
	};
	gps.calculateDistance = function(lat1, lon1, lat2, lon2, unit) {
		var radLat1 = gps.convertDegreeToRadian(lat1);
		var radLon1 = gps.convertDegreeToRadian(lon1);
		var radLat2 = gps.convertDegreeToRadian(lat2);
		var radLon2 = gps.convertDegreeToRadian(lon2);
		var distance;
		var distanceAlgorithm = 'HERVERSINE';
		switch (distanceAlgorithm) {
			case 'HERVERSINE':
				distance = gps.calculateDistanceByHeversine(radLat1, radLon1, radLat2, radLon2);
				break;
			default:
				distance = gps.calculateDistanceBySphericalLaw(radLat1, radLon1, radLat2, radLon2);
				break;
		}
		//$.i('distance: ' + distance + ' km');
		unit = unit || 'KM';
		if (distance != null) {
			switch (unit) {
				case 'M':
					return distance * 1000;
				default:
					return distance;
			}
		}
	};
	gps.calculateDistanceBySphericalLaw = function(radLat1, radLon1, radLat2, radLon2) {
		var R = 6317;
		var a = Math.sin(radLat1) * Math.sin(radLat2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.cos(radLon2 - radLon1);
		var d = Math.acos(a) * R;
		return d;
	};
	gps.calculateDistanceByHeversine = function(radLat1, radLon1, radLat2, radLon2) {
		var R = 6317;
		var dLat = radLat2 - radLat1;
		var dLon = radLon2 - radLon1;
		var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
		var d = R * c;
		return d;
	};
	gps.convertDegreeToRadian = function(degree) {
		return Math.PI * degree / 180;
	};
	gps.convertRadianToDegree = function(radian) {
		return radian * 180 / Math.PI;
	};
	module.exports = gps;
})();
